home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 17 / AMIGAplus Sonderheft 17 (1999)(ICP)(DE)[!].iso / dsound / source.lha / Mem.c < prev    next >
C/C++ Source or Header  |  1994-07-18  |  6KB  |  248 lines

  1.  
  2. /**************************************************************************/
  3. /*                   Mem.c                  */
  4. /*Contains code for reading an entire sample into memory at once      */
  5. /*This is used when it isn't practical to read the sound sample from      */
  6. /*disk as it is played (e.g. when the sample is on a floppy).             */
  7. /*Data is read in in blocks that are the same size as the buffer size      */
  8. /*(optionally) specified by the user using the -b flag, thereby not       */
  9. /*requiring the user to have a block of contiguous memory as large as      */
  10. /*the sample.                                  */
  11. /*The memory blocks are stored as a linked list;  there are two linked      */
  12. /*lists, one for each channel of a stereo sample (the list for the left   */
  13. /*channel is used if a mono sample is being played)              */
  14. /**************************************************************************/
  15.  
  16. #include <exec/types.h>
  17. #include <dos/dos.h>
  18. #include <dos/dosextens.h>
  19.  
  20. #include <proto/dos.h>
  21. #include <proto/exec.h>
  22.  
  23. #include "dsound.h"
  24.  
  25. extern BOOL loop;
  26.  
  27. typedef struct memBlock
  28. {
  29.    struct memBlock *next;  /*The next memory block in the list*/
  30.    ULONG blockLength;       /*The size of this memory block*/
  31. } memBlock;
  32.  
  33. /*The linked-list head pointers for each channel*/
  34. memBlock *left=NULL;
  35. memBlock *right=NULL;
  36.  
  37. memBlock *leftHeader=NULL;
  38. memBlock *rightHeader=NULL;
  39.  
  40. /*Read the sample (pointed to by file) into memory*/
  41. void storeLeft(BPTR file,ULONG length,ULONG blockLength)
  42. {
  43.    memBlock *temp;
  44.    memBlock *lastLeft;
  45.  
  46.    /*Loop while there's data to be stored...*/
  47.    while(length!=0)
  48.    {
  49.       /*Get the amount of data to be read next (max of blockLength bytes)*/
  50.       blockLength=MIN(blockLength,length);
  51.  
  52.       /*Allocate the memory*/
  53.       temp=(memBlock *)AllocMem(blockLength+8,0L);
  54.  
  55.       /*Exit if there was a problem*/
  56.       if(temp==NULL)
  57.       {
  58.      WriteMsg("Couldn't allocate needed memory\n");
  59.      cleanup(500);
  60.       }
  61.  
  62.       /*Get the length of the data block*/
  63.       temp->blockLength=blockLength;
  64.       temp->next=NULL;
  65.  
  66.       if(left==NULL)
  67.      leftHeader=left=lastLeft=temp;  /*First block of data...*/
  68.       else
  69.       {        /* Add another block to the end of the list*/
  70.      lastLeft->next=temp;
  71.      lastLeft=temp;
  72.       }
  73.  
  74.       /*Actually read the data, now that the allocated memory block*/
  75.       /*is in place*/
  76.       Read(file,lastLeft+1,blockLength);
  77.  
  78.       /*Subtract the amount read from the total yet to read*/
  79.       length-=blockLength;
  80.    }
  81.  
  82.    return;
  83. }
  84.  
  85. /*Delete any remaining memory blocks associated with the left channel*/
  86. void deleteLeft(void)
  87. {
  88.    memBlock *temp,*next;
  89.  
  90.    if(leftHeader==NULL)
  91.       next=left;
  92.    else
  93.       next=leftHeader;
  94.  
  95.    /*Loop until we run out of memory blocks*/
  96.    while(next!=NULL)
  97.    {
  98.       /*Get the next block*/
  99.       temp=next;
  100.       next=temp->next;
  101.  
  102.       /*Free the current block*/
  103.       FreeMem(temp,temp->blockLength+8);
  104.    }
  105.  
  106.    return;
  107. }
  108.  
  109. /*Get the next available block of sample data associated with the */
  110. /*left channel*/
  111. void getLeft(APTR dest)
  112. {
  113.    memBlock *temp;
  114.  
  115.    /*If there is no dest left, do nothing*/
  116.    if(dest==NULL)
  117.       return;
  118.  
  119.    /*If there is no data left, try to start over from the beginning*/
  120.    if(left==NULL)
  121.    {
  122.       if(leftHeader==NULL)
  123.      return;
  124.       left=leftHeader;
  125.    }
  126.  
  127.    /*Copy the sample data from the memory block to the destination buffer*/
  128.    CopyMem(left+1,dest,left->blockLength);
  129.  
  130.    /*Set the next block as the head of the list*/
  131.    temp=left;
  132.    left=left->next;
  133.  
  134.    /*Free the memory whose contents we just copied, if we're not looping*/
  135.    if(loop==FALSE)
  136.    {
  137.       FreeMem(temp,temp->blockLength+8);
  138.       leftHeader=NULL;
  139.    }
  140.  
  141.    return;
  142. }
  143.  
  144. /*Read the sample (pointed to by file) into memory*/
  145. void storeRight(BPTR file,ULONG length,ULONG blockLength)
  146. {
  147.    memBlock *temp;
  148.    memBlock *lastRight;
  149.  
  150.    /*Loop while there's data to be stored...*/
  151.    while(length!=0)
  152.    {
  153.       /*Get the amount of data to be read next (max of blockLength bytes)*/
  154.       blockLength=MIN(blockLength,length);
  155.  
  156.       /*Allocate the memory*/
  157.       temp=(memBlock *)AllocMem(blockLength+8,0L);
  158.  
  159.       /*Exit if there was a problem*/
  160.       if(temp==NULL)
  161.       {
  162.      WriteMsg("Couldn't allocate needed memory\n");
  163.      cleanup(500);
  164.       }
  165.  
  166.       /*Get the length of the data block*/
  167.       temp->blockLength=blockLength;
  168.       temp->next=NULL;
  169.  
  170.       if(right==NULL)
  171.      rightHeader=right=lastRight=temp;  /*First block of data...*/
  172.       else
  173.       {        /* Add another block to the end of the list*/
  174.      lastRight->next=temp;
  175.      lastRight=temp;
  176.       }
  177.  
  178.       /*Actually read the data, now that the allocated memory block*/
  179.       /*is in place*/
  180.       Read(file,lastRight+1,blockLength);
  181.  
  182.       /*Subtract the amount read from the total yet to read*/
  183.       length-=blockLength;
  184.    }
  185.  
  186.    return;
  187. }
  188.  
  189. /*Delete any remaining memory blocks associated with the right channel*/
  190. void deleteRight(void)
  191. {
  192.    memBlock *temp,*next;
  193.  
  194.    if(rightHeader==NULL)
  195.       next=right;
  196.    else
  197.       next=rightHeader;
  198.  
  199.    /*Loop until we run out of memory blocks*/
  200.    while(next!=NULL)
  201.    {
  202.       /*Get the next block*/
  203.       temp=next;
  204.       next=temp->next;
  205.  
  206.       /*Free the current block*/
  207.       FreeMem(temp,temp->blockLength+8);
  208.    }
  209.  
  210.    return;
  211. }
  212.  
  213. /*Get the next available block of sample data associated with the */
  214. /*right channel*/
  215. void getRight(APTR dest)
  216. {
  217.    memBlock *temp;
  218.  
  219.    /*If there is no dest, do nothing*/
  220.    if(dest==NULL)
  221.       return;
  222.  
  223.    /*If there is no data right, try to start over from the beginning*/
  224.    if(right==NULL)
  225.    {
  226.       if(rightHeader==NULL)
  227.      return;
  228.       right=rightHeader;
  229.    }
  230.  
  231.    /*Copy the sample data from the memory block to the destination buffer*/
  232.    CopyMem(right+1,dest,right->blockLength);
  233.  
  234.    /*Set the next block as the head of the list*/
  235.    temp=right;
  236.    right=right->next;
  237.  
  238.    /*Free the memory whose contents we just copied, if we're not looping*/
  239.    if(loop==FALSE)
  240.    {
  241.       FreeMem(temp,temp->blockLength+8);
  242.       rightHeader=NULL;
  243.    }
  244.  
  245.    return;
  246. }
  247.  
  248.